#include "OgreApp.h"

#include "OgreConfigFile.h"
#include "OgreException.h"
#include "OgreLogManager.h"
#include "OgreMeshManager.h"
#include "OgreRoot.h"

OgreApp::OgreApp()
{
#ifdef _DEBUG
    root = new Ogre::Root("plugins_d.cfg");
#else
    root = new Ogre::Root("plugins.cfg");
#endif

    Ogre::ConfigFile cf;
#ifdef _DEBUG
    cf.load("resources_d.cfg");
#else
    cf.load("resources.cfg");
#endif

    // Go through all sections & settings in the file
    Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();

    Ogre::String secName, typeName, archName;
    while (seci.hasMoreElements())
    {
        secName = seci.peekNextKey();
        Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
        Ogre::ConfigFile::SettingsMultiMap::iterator i;
        for (i = settings->begin(); i != settings->end(); ++i)
        {
            typeName = i->first;
            archName = i->second;
            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
                archName, typeName, secName);
        }
    }

	// Restore the old config
	if(!root->restoreConfig())
	{
		// If there is no existing config, bring up the config dialog
		if(!root->showConfigDialog())
		{
			// If the user cancels the dialog, close the app
			exit(0);
		}
	}

    win = root->initialise(true, "Ogre Framework");

	sceneMgr = root->createSceneManager(Ogre::ST_GENERIC, "MainSceneManager");

    camera = sceneMgr->createCamera("SimpleCamera");
    viewPort = root->getAutoCreatedWindow()->addViewport(camera);
    viewPort->setBackgroundColour(Ogre::ColourValue(0,0,0));
    camera->setAspectRatio(Ogre::Real(viewPort->getActualWidth()) / Ogre::Real(viewPort->getActualHeight()));
    camera->setNearClipDistance(1.0);

	Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

    createScene();

    listener = new DeviceListener(win, camera, sceneMgr);
    root->addFrameListener(listener);
}

OgreApp::~OgreApp()
{
    delete listener;
    delete root;
}

void OgreApp::start()
{
    root->startRendering();
}

void OgreApp::createScene()
{
	sceneMgr->setAmbientLight(Ogre::ColourValue(0.6f, 0.6f, 0.6f));
	sceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);

	node = sceneMgr->getRootSceneNode()->createChildSceneNode("OgreHead");
	ent = sceneMgr->createEntity("Ogre", "ogrehead.mesh");
	node->attachObject(ent);
	node->setPosition(0, 50, 0);


	node = sceneMgr->getRootSceneNode()->createChildSceneNode("CubeNode");
	ent = sceneMgr->createEntity("Cube", "cube.mesh");
	node->scale(0.75, 0.75, 0.75);
	ent->setMaterialName("CubeMaterial");
	node->attachObject(ent);
	node->setPosition(0, 50, -8);
	node->yaw(Ogre::Degree(45));

	node = sceneMgr->getRootSceneNode()->createChildSceneNode("CameraNode");
	node->setPosition(0, 100, 200);
	node = node->createChildSceneNode("PitchNode");
	node->attachObject(camera);
	node->pitch(Ogre::Degree(-20));

	// Create a ground plane
	Ogre::Plane plane(Ogre::Vector3::UNIT_Y, 0);
    Ogre::MeshManager::getSingleton().createPlane("ground",
       Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
       1000,1000,20,20,true,1,5,5,Ogre::Vector3::UNIT_Z);
    ent = sceneMgr->createEntity("GroundEntity", "ground");
    sceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);
    ent->setMaterialName("Ground");
    ent->setCastShadows(false);

	light = sceneMgr->createLight("sun");
	light->setType(Ogre::Light::LT_SPOTLIGHT);
	light->setPosition(500, 500, 0);
	light->setDirection(-1,-1,0);
}